package com.tangula.web.kashine.business;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.tangula.core.Logging;
import com.tangula.web.form.DefaultPagingBody;
import com.tangula.web.kashine.entity.AccountEntity;
import com.tangula.web.kashine.entity.HistoryEntity;
import com.tangula.web.kashine.entity.IntegerForm;
import com.tangula.web.kashine.entity.OrgForm;
import com.tangula.web.kashine.entity.OrgStudentForm;
import com.tangula.web.kashine.entity.OrgStudentRefEntity;
import com.tangula.web.kashine.entity.OrgTeacherForm;
import com.tangula.web.kashine.entity.PagableForm;
import com.tangula.web.kashine.entity.SaleProducesForm;
import com.tangula.web.kashine.entity.SendMoney;
import com.tangula.web.kashine.entity.SendMoneyToTeacherForm;
import com.tangula.web.kashine.entity.StoreEntity;
import com.tangula.web.kashine.entity.StudentAccountForm;
import com.tangula.web.kashine.entity.StudentOrganizationRefEntity;
import com.tangula.web.kashine.entity.StudentProductEntity;
import com.tangula.web.kashine.entity.TeacherForm;
import com.tangula.web.kashine.repository.AccountEntityRepository;
import com.tangula.web.kashine.repository.HistoryEntityRepository;
import com.tangula.web.kashine.repository.OrgStudentRefEntityRepository;
import com.tangula.web.kashine.repository.ProductEntityRepository;
import com.tangula.web.kashine.repository.StoreRepository;
import com.tangula.web.kashine.repository.StudentOrganizationRefRepository;
import com.tangula.web.kashine.repository.StudentProductRepository;







@Service
public class OrgBusinessImpl implements OrgBusiness, Logging{

	@Autowired
	AccountEntityRepository accRepo;
	
	
	@Autowired
	ProductEntityRepository productEntityRepository;
	@Autowired
	StudentOrganizationRefRepository studentRefRepository;
	@Autowired
	HistoryEntityRepository historyRepository;
	@Autowired
	StoreRepository storeRepository;
	@Autowired
	StudentProductRepository spRepo;
	
	@Autowired
	OrgStudentRefEntityRepository orgStuRepo;
	@Override
	public AccountEntity removeOrgTeacher(TeacherForm teacher) {
		if(teacher!=null) {
		AccountEntity t = accRepo.findById(teacher.getCondition()).get();
		t.setParentOrgOfTeacher(null);
		return accRepo.saveAndFlush(t);
		}else {
			return null;
		}
	}
	@Override
	public AccountEntity addOrgTeacher(OrgTeacherForm orgteacher) {
		if(orgteacher!=null) {
			AccountEntity t = accRepo.findById(orgteacher.getTeacherId()).get();
			t.setParentOrgOfTeacher(orgteacher.getOrgId());
		return accRepo.saveAndFlush(t);
		}else {
			return null;
		}
	}

	@Override
	public boolean addOrgStudent(OrgStudentForm orgstudent) {
		if(orgstudent!=null) {
			String orgId = orgstudent.getOrgId();
			String studentId = orgstudent.getStudentId();
			if(!orgStuRepo.existsByOrgIdAndStudentId(orgId, studentId)) {
				OrgStudentRefEntity entity = new OrgStudentRefEntity();
				entity.setOrgId(orgId);
				entity.setStudentId(studentId);
				entity.setMoney("0");
				return orgStuRepo.saveAndFlush(entity)!=null;
			}else {
				return true;   
			}
			
		}else {
			return true;
		}
	}
	@Override
	public List<AccountEntity> assignCash(SendMoneyToTeacherForm send) {
		if(send!=null) {
			List<SendMoney> lists = send.getSendMoney();
			List<AccountEntity> l = new ArrayList<AccountEntity>();
			for (SendMoney list : lists) {
				AccountEntity account = new AccountEntity();
				HistoryEntity history  = new HistoryEntity();
				account = accRepo.findById(list.getTeacherId()).get();
				account.setMoney(list.getAssignMoney()+account.getMoney());
				l.add(accRepo.saveAndFlush(account));
				history.setDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
				history.setHistoryDes("org send money");
				history.setMoney(list.getAssignMoney());
				history.setResavId(list.getTeacherId());
				history.setChange("+");
				historyRepository.saveAndFlush(history);
			}
			return l;
		}else {
			return null;
		}
	}
	@Override
	public DefaultPagingBody<AccountEntity> loadOrg(PagableForm pag) {
		if(pag!=null) {
			
			PageRequest pr = PageRequest.of(pag.getIndex()-1, pag.getSize(), Sort.by(new Sort.Order(Direction.ASC, "id")));
			
			Page<AccountEntity> list = accRepo.findByType("ORGANIZATION", pr);
			
			 DefaultPagingBody<AccountEntity> d = new DefaultPagingBody<>(pag.getIndex(),
					 pag.getSize(),
					 list.getNumberOfElements(), 
					 list.getContent());
			return d;
		}else {
			return null;
		}
	}
	@Override
	public AccountEntity changeStatusToN(OrgForm org) {
		if(org!=null) {
			AccountEntity orga = accRepo.findById(org.getCondition()).get();
			orga.setIsAcceptApprove("n");
			return accRepo.saveAndFlush(orga);
		}else {
			return null;
		}
	}
	@Override
	public IntegerForm loadOrgSize(OrgForm org) {
		if(org!=null) {
			List<AccountEntity> teacher = accRepo.findByParentOrgOfTeacherAndBlock(org.getCondition(),"y");
			List<StudentOrganizationRefEntity> student = studentRefRepository.findByOrgId(org.getCondition());
			List<StoreEntity> store = storeRepository.findByOwnerOrganizationAndStatus(org.getCondition(),"y");
			IntegerForm i = new IntegerForm(teacher.size(), student.size(), store.size());
			return i;
		}else {
			return null;
		}
	}
	@Override
	public AccountEntity blockOrg(OrgForm org) {
		if(org!=null) {
			AccountEntity account = accRepo.findById(org.getCondition()).get();
			account.setBlock("n");
			return accRepo.saveAndFlush(account);
		}else {
			return null;
		}
	}
	@Override
	public DefaultPagingBody<AccountEntity> showNoOrgTeacher(PagableForm pag) {
		if(pag!=null) {
			DefaultPagingBody<AccountEntity> d = new DefaultPagingBody<>(pag.getIndex(),
					pag.getSize(),
					accRepo.findByParentOrgOfTeacherAndTypeAndBlock(null, "teacher", "y").size(), 
					accRepo.findByParentOrgOfTeacherAndTypeAndBlock(null, "teacher", "y", PageRequest.of(pag.getIndex()-1, pag.getSize(), Sort.by(new Sort.Order(Direction.ASC, "id")))));
			return d;
		}else {
			return null;
		}
	}
	@Override
	public AccountEntity unblockOrg(OrgForm org) {
		if(org!=null) {
			AccountEntity account = accRepo.findById(org.getCondition()).get();
			account.setBlock("y");
			return accRepo.saveAndFlush(account);
		}else {
			return null;
		}
	}
	@Override
	public AccountEntity changeStatusToY(OrgForm org) {
		if(org!=null) {
			AccountEntity orga = accRepo.findById(org.getCondition()).get();
			orga.setIsAcceptApprove("y");
			return accRepo.saveAndFlush(orga);
		}else {
			return null;
		}
	}
	@Override
	public AccountEntity blockOrUnBlockOrg(OrgForm org) {
		if(org!=null) {
			return accRepo.findById(org.getCondition()).get();
		}else {
			return null;
		}
	}
	@Override
	public boolean removeOrgStudent(String student, String orgId) {
		if(student!=null&&orgId!=null) {
			StudentOrganizationRefEntity sor = studentRefRepository.findByStudentIdAndOrgId(student, orgId);
			studentRefRepository.delete(sor);
			if(studentRefRepository.findByStudentEmailAndOrgId(student, orgId)==null) {
				return true;
			}else {
				return false;
			}
		}else {
			return false; 
		}
	}
	
	
	@Override
	public boolean removeOrgStudentById(String orgId, String studentId) {
		OrgStudentRefEntity entity = orgStuRepo.findByOrgIdAndStudentId(orgId, studentId);
		if(entity!=null) {
			orgStuRepo.delete(entity);
			orgStuRepo.flush();
		}
		return true;
	}
	
	@Override
	public Boolean saleProductToStudent(SaleProducesForm sale) {
		if(sale!=null) {
			List<String> proIds = sale.getProductIds();
			int money = 0;
			for (String proId : proIds) {
				money += productEntityRepository.findById(proId).get().getProductPrice();
			}
			if(money>accRepo.findByEmail(sale.getStuId()).getMoney()) {
				return false;
			}else {
				List<StudentProductEntity> lists = new ArrayList<StudentProductEntity>();
				for(int i=0;i<proIds.size();i++) {
					StudentProductEntity spe = new StudentProductEntity();
					spe.setProductId(proIds.get(i));
					spe.setStudentId(sale.getStuId());
					spe.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
					lists.add(spRepo.saveAndFlush(spe));
				}
				if(lists.size()!=proIds.size()) {
					return false;
				}else {
					return true;
				}
			}
		}else {
			return false;
		}
	}
	
	
	@Override
	public DefaultPagingBody<StudentAccountForm> loadStudentsOutOfOrg(PagableForm page) {
		if (page != null) {
			Sort sort = new Sort(Direction.DESC, "id");
			
			List<AccountEntity> lists = accRepo.findByStudentsOutOfOrg(page.getCondition(), PageRequest.of(page.getIndex()-1, page.getSize(), sort));
			
			int count = accRepo.countByStudentsOutOfOrg(page.getCondition());
			
			List<StudentAccountForm> items = new ArrayList<>(lists.size());
			
			lists.stream().map(in->new StudentAccountForm(in.getId(), in.getName(), in.getImage(), in.getAccountDesc())).forEach(
					it->{
						items.add(it);
					}
				
			);
			
			DefaultPagingBody<StudentAccountForm> ap = new DefaultPagingBody<StudentAccountForm>(page.getIndex(), page.getSize(), count,items);
			return ap;
		} else {
			return null;
		}
	}
	@Override
	public boolean block(String id) {
		AccountEntity entity = accRepo.findById(id).orElse(null);
		
		if(entity!=null) {
			entity.setBlock("n");
			accRepo.saveAndFlush(entity);
		}
		
		return true;
	}
	@Override
	public boolean unblock(String id) {
		AccountEntity entity = accRepo.findById(id).orElse(null);
		
		if(entity!=null) {
			entity.setBlock("y");
			accRepo.saveAndFlush(entity);
		}
		
		return true;
	}
	@Override
	public AccountEntity loadOrgDetail(String id) {
		return accRepo.findById(id).orElse(null);
	}

}
